﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Http.Results;
using System.Web.Mvc;
using System.Web.Routing;

namespace AspDotNet.Framework.Mvc.FirstDemo.Controllers
{
    public class ErrorHandlerController : Controller
    {
        public ActionResult Index()
        {
            return null;
        }

        [HandleError]
        [HandleError(ExceptionType = typeof(Exception), View = "~/Views/Home/Index.cshtml")]
        public ActionResult Error1()
        {
            throw new NotImplementedException();
        }

        [HandleException]
        public ActionResult Error2()
        {
            throw new NotImplementedException();
        }
    }

    public class HandleExceptionAttribute : HandleErrorAttribute, IExceptionFilter
    {
        #region IExceptionFilter Members

        public override void OnException(ExceptionContext filterContext)
        {
            if (filterContext == null)
            {
                throw new ArgumentNullException(nameof(filterContext));
            }
            if (filterContext.IsChildAction)
            {
                return;
            }

            // If custom errors are disabled, we need to let the normal ASP.NET exception handler
            // execute so that the user can see useful debugging information.
            if (filterContext.ExceptionHandled || !filterContext.HttpContext.IsCustomErrorEnabled)
            {
                return;
            }

            Exception exception = filterContext.Exception;

            // If this is not an HTTP 500 (for example, if somebody throws an HTTP 404 from an action method),
            // ignore it.
            if (new HttpException(null, exception).GetHttpCode() != 500)
            {
                return;
            }

            if (!ExceptionType.IsInstanceOfType(exception))
            {
                return;
            }

            string actionName = (string)filterContext.RouteData.Values["action"];
            filterContext.Controller.ViewData["Exception"] = exception;
            if (exception.GetType() == typeof(NullReferenceException))/* 一系列判断 */
            {
                filterContext.Result = new ViewResult()
                {
                    ViewName = "Index",
                    ViewData = filterContext.Controller.ViewData
                };
            }
            else if (exception.GetType() == typeof(NotImplementedException))
            {
                filterContext.Result = new System.Web.Mvc.RedirectToRouteResult(
                    new RouteValueDictionary()
                    {
                        { "controller", "Home" },
                        { "action", "Index" },
                    });
            }
            else if (true)
            {
                filterContext.Result = new ViewResult()
                {
                    ViewName = "~/Views/Shared/Error.cshtml"
                };
            }
            filterContext.ExceptionHandled = true;
            filterContext.HttpContext.Response.Clear();
            filterContext.HttpContext.Response.StatusCode = 500;
            filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
        }

        #endregion
    }

}